package com.zyf.project.binaryproto.specification.impl;

import com.zyf.project.binaryproto.annotation.DataField;
import com.zyf.project.binaryproto.codec.NumberEncoding;
import com.zyf.project.binaryproto.specification.DataSpecification;
import com.zyf.project.binaryproto.specification.EnumSpecification;
import com.zyf.project.binaryproto.specification.FieldSpecification;
import com.zyf.project.binaryproto.type.PrimitiveType;

/**
 * <h1>{@link FieldSpecification} 的实现类</h1>
 * <p>实际上也就是一个 POJO</p>
 *
 * @author Zhou Yifan
 */
public class FieldSpecificationInfo implements FieldSpecification {

    private int order;

    private String name;

    private String description;

    private boolean repeatable;

    private PrimitiveType primitiveType;

    private NumberEncoding numberEncoding;

    private EnumSpecification enumSpecification;

    private DataSpecification dataSpecification;

    private int maxSize;

    private Class<?> dataType;

    private boolean isGenericContract = false;

    public FieldSpecificationInfo(int order, String name, String description, PrimitiveType primitiveType,
                                  NumberEncoding numberEncoding, boolean repeatable, int maxSize, Class<?> dataType) {
        if (primitiveType == null) {
            throw new IllegalArgumentException("primitiveType is null!");
        }
        this.order = order;
        this.name = name;
        this.description = description;
        this.primitiveType = primitiveType;
        this.numberEncoding = numberEncoding;
        this.repeatable = repeatable;
        this.maxSize = maxSize;
        this.dataType = dataType;
    }

    public FieldSpecificationInfo(int order, String name, String description, EnumSpecification enumSpecification, boolean repeatable,
                                  Class<?> enumType) {
        if (enumSpecification == null) {
            throw new IllegalArgumentException("enum specification is null!");
        }
        this.order = order;
        this.name = name;
        this.description = description;
        this.enumSpecification = enumSpecification;
        this.repeatable = repeatable;
        this.maxSize = -1;
        this.dataType = enumType;
    }

    public FieldSpecificationInfo(int order, String name, String description, DataSpecification dataSpecification,
                                  boolean repeatable, Class<?> contractType, boolean isGenericContract) {
        if (dataSpecification == null) {
            throw new IllegalArgumentException("contractType is null!");
        }
        this.order = order;
        this.name = name;
        this.description = description;
        this.dataSpecification = dataSpecification;
        this.repeatable = repeatable;
        this.maxSize = -1;
        this.dataType = contractType;
        this.isGenericContract = isGenericContract;
    }

    /**
     * 字段名称
     *
     * @return 字符串
     */
    @Override
    public String getName() {
        return name;
    }

    /**
     * 字段描述
     *
     * @return 字符串
     */
    @Override
    public String getDescription() {
        return description;
    }

    /**
     * <p>字段值的类型</p>
     * <p>如果不是基本类型则返回 null，即 {@link DataField#primitiveType()} 设置为 {@link PrimitiveType#NIL}</p>
     *
     * @return {@link PrimitiveType}
     */
    @Override
    public PrimitiveType getPrimitiveType() {
        return primitiveType;
    }

    /**
     * 数值编码方式，只有 {@link DataField#primitiveType()} 为整数时（INT8 ~ INT64）时才有效
     *
     * @return {@link NumberEncoding}
     */
    @Override
    public NumberEncoding getNumberEncoding() {
        return numberEncoding;
    }

    /**
     * 字段值引用的枚举契约
     *
     * @return {@link EnumSpecification}
     */
    @Override
    public EnumSpecification getRefEnum() {
        return enumSpecification;
    }

    /**
     * 字段引用的数据契约，如果不是数据契约的类型，则返回 null
     *
     * @return {@link DataSpecification}
     */
    @Override
    public DataSpecification getRefContract() {
        return dataSpecification;
    }

    /**
     * 是否是多值列表，或者说是否可重复
     *
     * @return 布尔值
     */
    @Override
    public boolean isRepeatable() {
        return repeatable;
    }

    /**
     * 最大长度（可变长度的最大长度），可以参考 {@link DataField#maxSize()}
     *
     * @return int 值，表示的单位是 byte
     */
    @Override
    public int getMaxSize() {
        return maxSize;
    }

    /**
     * 是否引用了一个通用数据契约类型，实际的数据契约需要根据实际的对象列表来定
     *
     * @return 布尔值
     */
    @Override
    public boolean isGenericContract() {
        return isGenericContract;
    }

    public int getOrder() {
        return order;
    }

    public Class<?> getDataType() {
        return dataType;
    }
}
